Skip to content

ci(kosli): attest SBOMs with the sbom type - #1186

Merged
AlexKantor87 merged 1 commit into
mainfrom
claude/ci-attest-sbom-type
Sep 15, 2026
Merged

AlexKantor87 merged 1 commit into
mainfrom
claude/ci-attest-sbom-type

Conversation

@AlexKantor87

Copy link
Copy Markdown
Contributor

Switches all three SBOM attestations in this repo to kosli attest sbom.

workflow name was
docker.yml container-sbom attest generic
binary_provenance.yml sbom attest generic
binary_provenance.yml cyclone-dx-sbom attest custom --type cyclone-dx-1-6

Why

The generic ones carried the document only as an opaque attachment. The custom one sent it as attestation data.

The sbom type takes the file with --sbom-file and reads the format, creation time, tools, subject and package count out of it. The trail then shows what the document says.

Template slots

Fifteen slots that receive these move from generic to "*". One is in main-flow-template.yml. Fourteen are in release-flow-template.yml, one per binary artifact plus the container.

Both files are applied by init_kosli.yml with kosli create flow --template-file, which is an upsert on every run. A slot naming only sbom would refuse the old shape from a run still in flight. main.yml cancels concurrent runs per branch, so that window is short. release.yml does not cancel, and two overlapping releases would hit it.

Names and external URLs are unchanged, so existing slots and anything referring to them keep matching.

Prerequisite, verified

The type is behind the per-organisation flag is-sbom-attestation-enabled. I ran kosli attest sbom against production in kosli-public and it was accepted, so the flag is on where these workflows report.

Follow-up

Narrow the slots from "*" to sbom once nothing reports the old shapes. The cyclone-dx-1-6 custom type is still created elsewhere and old trails reference it, so removing it is a separate decision.

🤖 Generated with Claude Code

Three SBOM attestations move off the generic and custom types. The sbom
type is in production and v2.41.0 carries the command, which the org-wide
KOSLI_CLI_VERSION of 2 already installs.

  docker.yml            container-sbom      was attest generic
  binary_provenance.yml sbom                was attest generic
  binary_provenance.yml cyclone-dx-sbom     was attest custom cyclone-dx-1-6

The generic ones carried the document only as an opaque attachment. The
custom one sent it as attestation data. The sbom type takes the file with
--sbom-file and reads the format, creation time, tools, subject and package
count out of it, so the trail shows what the document says rather than a
blob you have to download.

Names and external URLs are unchanged, so existing template slots and
anything referring to them keep matching.

Fifteen template slots that receive these move from generic to "*": one in
main-flow-template.yml, fourteen in release-flow-template.yml. Both files
are applied by init_kosli.yml with kosli create flow --template-file, an
upsert on every run, so a slot naming only sbom would refuse the old shape
from a run still in flight. main.yml cancels concurrent runs per branch so
that window is short; release.yml does not cancel, and two overlapping
releases would hit it. Narrowing to sbom is the follow-up once nothing
reports the old shapes.

The cyclone-dx-1-6 custom type is still created elsewhere. Old trails
reference it, so removing it is a separate decision.

The type is behind the per-organisation flag is-sbom-attestation-enabled.
Alex confirms it is on for kosli-public, which both workflows report to;
not independently verified here.

search: grep -rn "kosli attest" .github/workflows/ read in full. An earlier
        search of mine piped 31 matching lines through head -8 and missed
        binary_provenance.yml entirely.
verified: ran the released binary with the exact flag set these workflows
        use, against a real SPDX fixture. It accepted --fingerprint, --name,
        --sbom-file, --external-url, --flow, --trail and --org, parsed the
        file, and failed only on the deliberately invalid token.
mutation: not applicable, no test asserted here

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Claude finished @AlexKantor87's task in 3m 40s —— View job


Review: ci(kosli): attest SBOMs with the sbom type

  • Read the diff (git diff origin/main...HEAD)
  • Static checks — go build ./... and go vet ./... both clean (no Go code changed; no dependency changes, so go mod tidy is a no-op here)
  • Checked kosli attest sbom flags, parsing and limits
  • Traced workflow wiring (main.yml / release.ymlinit_kosli.yml, docker.yml, binary_provenance.yml)
  • Posted 4 inline comments

The change itself is right and the flag mapping is correct: --sbom-file is required and mutually exclusive with --attachments (cmd/kosli/attestSbom.go:162-167), --external-url is still available via addAttestationFlags, and syft's spdx-json / cyclonedx-json are both handled by internal/sbom.ProcessSBOM. The beta annotation on the command is docs-only — there's no runtime gate to worry about.

My concerns are all about rollout, not about the edit.

Blocking-ish: nothing here proves the new commands run

main.yml:60-66 sets report_to_kosli=none for pull_request events, so none of the three changed steps execute in this PR's CI. A green check here says nothing about them. Worse, binary_provenance.yml is only called from release.yml:243 — so two of the three steps are first exercised during a real release, where a failure blocks the release pipeline.

Two things I'd verify before merging:

  1. vars.KOSLI_CLI_VERSIONv2.41.0. attest sbom landed yesterday (11306cde, feat(attest-sbom): add kosli attest sbom #1168) and v2.41.0 (tagged today) is the first tag containing it. Every one of these jobs installs the CLI via setup-cli-action@v5 at that repo variable. If it still points at v2.40.x, the docker step fails on the first push to main and the binary steps fail on the next release. The PR description verifies the is-sbom-attestation-enabled org flag but not this.
  2. kosli create flow --template-file accepts type: "*". newFlowForm uploads the template as an opaque form part (cmd/kosli/createFlow.go:201) — there is no client-side validation, and "*" appears nowhere else in this repo. init-kosli is a needs: dependency of test, docker and the release jobs, so a template the server won't accept takes down the whole pipeline, not just the SBOM steps. Running it once against a scratch flow and noting the result in the PR body would close this.

Smaller points (all inline)

  • 9 MiB cap is new. attest sbom enforces it client-side (attestSbom.go:23, :236); attest generic --attachments did not. Current SBOMs are nowhere near it — noted so it isn't a surprise later.
  • cyclone-dx-1-6 evaluation is lost now, not later. Whatever schema/compliance rules that custom type carried go away with this step. Separately: sbom and cyclone-dx-sbom are now the same type over two renderings of the same syft scan, producing the same Kosli-side summary — worth asking whether both still earn their keep.
  • The "*" slots turn off type checking on 15 slots. The reasoning in the PR body is sound (the release.yml concurrency group has no cancel-in-progress, so overlapping releases really can straddle the upsert), and the trade is the right one for a migration. But wildcards stick unless something forces the narrowing — per this repo's CLAUDE.md slice discipline, a TODO.md entry or a tracking issue for "narrow "*"sbom" would make the follow-up real.

Good work

  • Names and external URLs left untouched, so existing slots and anything referencing them keep matching — that's the detail that makes this a safe in-place swap.
  • The "*" rollout window is reasoned about explicitly per workflow rather than assumed away, including the asymmetry between main.yml (cancels) and release.yml (doesn't).
  • Consistent treatment across all three attestation sites; the trail gains sbom_format / sbom_sha256 annotations and a checksum over the exact bytes uploaded, which is a real improvement over an opaque attachment.
  • The PR body's follow-up section correctly keeps the custom-type removal as a separate decision.
    · branch claude/ci-attest-sbom-type

Comment thread release-flow-template.yml
Comment thread .github/workflows/binary_provenance.yml
Comment thread .github/workflows/docker.yml
Comment thread .github/workflows/binary_provenance.yml
Comment thread release-flow-template.yml
Comment thread .github/workflows/docker.yml
Comment thread .github/workflows/binary_provenance.yml
@AlexKantor87
AlexKantor87 merged commit 461ebff into main Sep 15, 2026
24 of 25 checks passed
@AlexKantor87
AlexKantor87 deleted the claude/ci-attest-sbom-type branch September 15, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants